package dian.qing.li.demo.security.config.security;

import com.alibaba.fastjson.JSON;
import com.pactera.redis.utils.RedisUtils;
import dian.qing.li.demo.security.commons.RestException;
import dian.qing.li.demo.security.commons.RestResult;
import dian.qing.li.demo.security.constants.Constants;
import dian.qing.li.demo.security.constants.RedisKey;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 认证失败
 *
 * @author: liqingdian
 **/
@Slf4j
public class AppAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {
        log.error(ex.getMessage(), ex);
        String username = this.obtainUsername(request);
        Integer loginCount = 5;
        if (StringUtils.isNotBlank(username)) {
            String lockedKey = RedisUtils.redisKey(RedisKey.LOGIN_LOCKED, username);
            loginCount = RedisUtils.get(lockedKey, Integer.class);
            loginCount = loginCount == null ? 5 : loginCount;
            RedisUtils.put(lockedKey, --loginCount, 5 * 60);
        }
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter out = response.getWriter();
        RestResult failed = RestResult.failed(HttpServletResponse.SC_UNAUTHORIZED, "登陆失败", loginCount);
        if (ex instanceof UsernameNotFoundException || ex instanceof BadCredentialsException) {
            failed.setMsg("账号或密码错误");
        } else if (ex instanceof DisabledException) {
            failed.setMsg("账户被禁用");
        } else if (ex instanceof LockedException) {
            failed.setMsg("账户锁定");
        } else if (ex instanceof AccountExpiredException) {
            failed.setMsg("账户过期");
        } else if (ex.getCause() instanceof RestException) {
            failed.setMsg(ex.getMessage());
        }
        out.write(JSON.toJSONString(failed, Constants.FASTJSON_SERIALIZER));
        out.flush();
        out.close();
    }

    private String obtainUsername(HttpServletRequest request) {
        return request.getParameter(Constants.USERNAME_PARAMETER);
    }
}
